using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ScannerLib.Visualizer
{
    
    public partial class LineHoughVisualizer : Control
    {
        private Bitmap m_bitmap;
        private LineHoughSettings m_settings = new LineHoughSettings(1, 360);
        private List<Point> m_houghPoints;

        public LineHoughVisualizer()
        {
            SetStyle(ControlStyles.Opaque, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            InitializeComponent();
            DoubleBuffered = true;
        }

        public LineHoughSettings HoughSettings
        {
            get
            {
                return m_settings;
            }

            set
            {
                m_settings = value ?? new LineHoughSettings(1,360);
            }
        }

        public Bitmap Bitmap
        {
            get
            {
                return m_bitmap;
            }

            set
            {
                m_bitmap = value;
            }
        }

        public List<Point> HoughPoints
        {
            get
            {
                return m_houghPoints;
            }

            set
            {
                m_houghPoints = value;
            }
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            // TODO: Add custom paint code here

            pe.Graphics.FillRectangle(Brushes.Black, ClientRectangle);

            try
            {
                if (m_bitmap != null)
                    pe.Graphics.DrawImage(m_bitmap, ClientRectangle);

                if (HoughPoints != null && m_bitmap != null)
                {
                    foreach (Point p in HoughPoints)
                    {
                        double theta = LineHoughSettings.RAD(p.X * 360.0 / HoughSettings.ThetaRes);
                        double ro = p.Y * HoughSettings.RoRes;

                        double s = Math.Sin(theta);
                        double c = Math.Cos(theta);


                        s = (s < 0 && s > -0.0001) ? 0 :
                                ((s > 0 && s < 0.0001) ? 0 : s);
                        c = (c < 0 && c > -0.0001) ? 0 :
                                ((c > 0 && c < 0.0001) ? 0 : c);


                        if (s == 0)
                        {
                            /* vertical line */
                            int x = (int)(-ro * m_bitmap.Width / (c * Width));

                            pe.Graphics.DrawLine(Pens.BlueViolet, x, 0, x, Height - 1);
                        }
                        else
                        {
                            double a = (c / s);
                            double b = (ro / s);

                            int x1, y1, x2, y2;

                            if (a > 1)
                            {
                                x1 = (int)(-b / a);
                                y1 = 0;

                                x2 = (int)((m_bitmap.Height - 1 - b) / a);
                                y2 = m_bitmap.Height - 1;


                            }
                            else
                            {
                                x1 = 0;
                                y1 = (int)b;

                                x2 = m_bitmap.Width - 1;
                                y2 = (int)((m_bitmap.Width - 1) * a + b);
                            }

                            pe.Graphics.DrawLine(Pens.BlanchedAlmond, 1.0f * x1 * Width / m_bitmap.Width, 1.0f * y1 * Height / m_bitmap.Height,
                                1.0f * x2 * Width / m_bitmap.Width, 1.0f * y2 * Height / m_bitmap.Height);
                        }
                    }
                }

            }
            catch { }
            // Calling the base class OnPaint
            base.OnPaint(pe);
        }
    }
}
